package com.googlecode.gaal.data.impl;

import java.util.Iterator;

import com.googlecode.gaal.data.api.Corpus;
import com.googlecode.gaal.data.api.IntSequence;
import com.googlecode.gaal.data.api.Multiset;

public abstract class AbstractCorpus<T> implements Corpus<T> {

    @Override
    public Iterator<T> iterator(final IntSequence sequence) {
        return new Iterator<T>() {
            private int index = 0;
            private int end = sequence.size();

            @Override
            public boolean hasNext() {
                return (index < end);
            }

            @Override
            public T next() {
                return toToken(sequence.get(index++));
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    @Override
    public String toString(IntSequence sequence, String delimiter) {
        return join(iterator(sequence), delimiter);
    }

    @Override
    public String toString(Multiset<IntSequence> sequenceSet, String delimiter) {
        StringBuilder buffer = new StringBuilder();
        boolean isFirst = true;
        buffer.append('{');
        for (IntSequence sequence : sequenceSet) {
            if (isFirst)
                isFirst = false;
            else
                buffer.append(',');
            buffer.append(String.format("\"%s\"=%d", join(iterator(sequence), delimiter),
                    sequenceSet.getQuantity(sequence)));
        }
        buffer.append('}');
        return buffer.toString();
    }

    @Override
    public String toString(Iterator<IntSequence> iterator, String delimiter) {
        StringBuilder buffer = new StringBuilder();
        boolean isFirst = true;
        buffer.append('{');
        while (iterator.hasNext()) {
            IntSequence sequence = iterator.next();
            if (isFirst)
                isFirst = false;
            else
                buffer.append(',');
            buffer.append(String.format("\"%s\"", join(iterator(sequence), delimiter)));
        }
        buffer.append('}');
        return buffer.toString();
    }

    public static <T> String join(Iterator<T> iterator, String delimiter) {
        if (!iterator.hasNext())
            return "";
        StringBuilder buffer = new StringBuilder(iterator.next().toString());
        while (iterator.hasNext())
            buffer.append(delimiter).append(iterator.next());
        return buffer.toString();
    }
}
